package com.org.devg.devgfilesync.utils;

import com.alibaba.fastjson.JSONObject;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

public class HttpUtil {

  private static final Logger log = LoggerFactory.getLogger(HttpUtil.class);

  private static final RequestConfig requestConfig = RequestConfig.custom()
      .setSocketTimeout(30000)
      .setConnectTimeout(30000)
      .setConnectionRequestTimeout(30000)
      .build();
  public static JSONObject httpRequest(String httpUrl, File file, String fileId, String filePath) {
    CloseableHttpClient httpClient = null;
    HttpResponse httpResponse = null;
    JSONObject jsonObject = new JSONObject();
    try {
      httpClient = HttpClients.createDefault();
      FileBody fileBody = new FileBody(file, ContentType.DEFAULT_BINARY);
      //MultipartEntityBuilder
      MultipartEntityBuilder builder = MultipartEntityBuilder.create();
      builder.addPart("file", fileBody);
      builder.addTextBody("filePath", filePath);
      builder.addTextBody("fileId", fileId);
      builder.setCharset(Charset.forName("UTF-8"));

      HttpEntity entity = builder.build();
      //HttpPost
      HttpPost httpPost = new HttpPost(httpUrl);
      httpPost.setConfig(requestConfig);
      httpPost.setEntity(entity);
      //执行提交
      httpResponse = httpClient.execute(httpPost);
      int returnCode = httpResponse.getStatusLine().getStatusCode();
      if (returnCode == HttpStatus.SC_OK) {
        HttpEntity httpEntity = httpResponse.getEntity();
        byte[] json = EntityUtils.toByteArray(httpEntity);
        String responseJson = new String(json, "UTF-8");
        jsonObject = JSONObject.parseObject(responseJson);
        //关闭流
        EntityUtils.consume(httpEntity);
      }
    } catch (Exception ex) {
      jsonObject.put("code", "500");
      jsonObject.put("message", ex.getMessage());
      log.error("upload file exception", ex);
    } finally {
      if (null != httpResponse) {
        try {
          ((CloseableHttpResponse) httpResponse).close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
      if (null != httpClient) {
        try {
          httpClient.close();
        } catch (IOException ex) {
          ex.printStackTrace();
        }
      }
    }
    return jsonObject;
  }


  public static <T> JSONObject httpRequest(String httpUrl, T t) {
    JSONObject jsonObject = new JSONObject();
    HttpResponse httpResponse = null;
    CloseableHttpClient httpClient = null;
    try {
      httpClient = HttpClients.createDefault();
      MultipartEntityBuilder multipartEntity = MultipartEntityBuilder.create().setMode(HttpMultipartMode.RFC6532);
      ContentType contentType = ContentType.create("text/plain", Charset.forName("UTF-8"));
      Class<? extends Object> tClass = t.getClass();
      Field[] fields = tClass.getDeclaredFields();
      if (null != fields && fields.length > 0) {
        for (int i = 0; i < fields.length; i++) {
          //设置可以访问私有变量
          fields[i].setAccessible(true);
          //获取属性的名字
          String fieldName = fields[i].getName();
          //将属性名字的首字母大写
          String firstChar = fieldName.substring(0, 1);
          fieldName = fieldName.replaceFirst(firstChar, firstChar.toUpperCase());
          Method m = tClass.getMethod("get" + fieldName);
          Object value = m.invoke(t);
          if (null != value) {
            String fieldTypeName = fields[i].getType().getName();
            switch (fieldTypeName) {
              case "java.math.BigDecimal":
                multipartEntity.addTextBody(fieldName, value.toString());
                break;
              case "java.lang.Long":
                multipartEntity.addTextBody(fieldName, value.toString());
                break;
              case "java.lang.Integer":
                multipartEntity.addTextBody(fieldName, value.toString());
                break;
              case "java.lang.String":
                StringBody stringBody = new StringBody(value.toString(), contentType);
                multipartEntity.addPart(fieldName, stringBody);
                break;
              case "java.io.File":
                FileBody fileBody = new FileBody((File) value);
                multipartEntity.addPart(fieldName, fileBody);
                break;
              case "org.springframework.web.multipart.MultipartFile":
                MultipartFile multipartFile = (MultipartFile) value;
                InputStream inputStream = multipartFile.getInputStream();
                String fileName = multipartFile.getOriginalFilename();
                multipartEntity.addBinaryBody(fieldName, inputStream, ContentType.MULTIPART_FORM_DATA, fileName);
                break;
              default:
                break;
            }
          }
        }
      }
      multipartEntity.setCharset(Charset.forName("UTF-8"));
      HttpEntity entity = multipartEntity.build();
      HttpPost httpPost = new HttpPost(httpUrl);
      httpPost.setConfig(requestConfig);
      httpPost.setEntity(entity);
      //执行提交
      httpResponse = httpClient.execute(httpPost);
      int returnCode = httpResponse.getStatusLine().getStatusCode();
      if (returnCode == HttpStatus.SC_OK) {
        HttpEntity httpEntity = httpResponse.getEntity();
        byte[] json = EntityUtils.toByteArray(httpEntity);
        String responseJson = new String(json, "UTF-8");
        jsonObject = JSONObject.parseObject(responseJson);
        //关闭流
        EntityUtils.consume(httpEntity);
      }
    } catch (Exception ex) {
      jsonObject.put("code", "500");
      jsonObject.put("message", ex.getMessage());
      log.error("upload file exception", ex);
    } finally {
      if (null != httpResponse) {
        try {
          ((CloseableHttpResponse) httpResponse).close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
      if (null != httpClient) {
        try {
          httpClient.close();
        } catch (IOException ex) {
          ex.printStackTrace();
        }
      }
    }
    return jsonObject;
  }
}
